using System;
using System.Runtime.Serialization;

namespace BanZuiCloudControlAgent.Utils.Exceptions
{
    /// <summary>
    /// 云控系统异常基类，所有自定义异常都应继承此类
    /// </summary>
    [Serializable]
    public class BanZuiException : Exception
    {
        /// <summary>
        /// 错误代码
        /// </summary>
        public string ErrorCode { get; }

        /// <summary>
        /// 错误来源模块
        /// </summary>
        public string Module { get; }

        /// <summary>
        /// 是否为致命错误
        /// </summary>
        public bool IsFatal { get; }

        /// <summary>
        /// 初始化BanZuiException类的新实例
        /// </summary>
        public BanZuiException() : base("云控系统发生未知错误")
        {
            ErrorCode = "E000";
            Module = "Unknown";
            IsFatal = false;
        }

        /// <summary>
        /// 使用指定的错误消息初始化BanZuiException类的新实例
        /// </summary>
        /// <param name="message">描述错误的消息</param>
        public BanZuiException(string message) : base(message)
        {
            ErrorCode = "E000";
            Module = "Unknown";
            IsFatal = false;
        }

        /// <summary>
        /// 使用指定的错误消息和对作为此异常原因的内部异常的引用来初始化BanZuiException类的新实例
        /// </summary>
        /// <param name="message">描述错误的消息</param>
        /// <param name="innerException">导致当前异常的异常</param>
        public BanZuiException(string message, Exception innerException) : base(message, innerException)
        {
            ErrorCode = "E000";
            Module = "Unknown";
            IsFatal = false;
        }

        /// <summary>
        /// 使用指定的错误代码和消息初始化BanZuiException类的新实例
        /// </summary>
        /// <param name="errorCode">错误代码</param>
        /// <param name="message">描述错误的消息</param>
        public BanZuiException(string errorCode, string message) : base(message)
        {
            ErrorCode = errorCode;
            Module = "Unknown";
            IsFatal = false;
        }

        /// <summary>
        /// 使用指定的错误代码、消息和内部异常初始化BanZuiException类的新实例
        /// </summary>
        /// <param name="errorCode">错误代码</param>
        /// <param name="message">描述错误的消息</param>
        /// <param name="innerException">导致当前异常的异常</param>
        public BanZuiException(string errorCode, string message, Exception innerException) : base(message, innerException)
        {
            ErrorCode = errorCode;
            Module = "Unknown";
            IsFatal = false;
        }

        /// <summary>
        /// 使用指定的错误代码、模块、消息和致命标志初始化BanZuiException类的新实例
        /// </summary>
        /// <param name="errorCode">错误代码</param>
        /// <param name="module">错误来源模块</param>
        /// <param name="message">描述错误的消息</param>
        /// <param name="isFatal">是否为致命错误</param>
        public BanZuiException(string errorCode, string module, string message, bool isFatal = false) : base(message)
        {
            ErrorCode = errorCode;
            Module = module;
            IsFatal = isFatal;
        }

        /// <summary>
        /// 使用指定的错误代码、模块、消息、致命标志和内部异常初始化BanZuiException类的新实例
        /// </summary>
        /// <param name="errorCode">错误代码</param>
        /// <param name="module">错误来源模块</param>
        /// <param name="message">描述错误的消息</param>
        /// <param name="isFatal">是否为致命错误</param>
        /// <param name="innerException">导致当前异常的异常</param>
        public BanZuiException(string errorCode, string module, string message, bool isFatal, Exception innerException) : base(message, innerException)
        {
            ErrorCode = errorCode;
            Module = module;
            IsFatal = isFatal;
        }

        /// <summary>
        /// 使用序列化数据初始化BanZuiException类的新实例
        /// </summary>
        /// <param name="info">SerializationInfo，它存有关于所引发的异常的序列化的对象数据</param>
        /// <param name="context">包含有关源或目标的上下文信息</param>
        protected BanZuiException(SerializationInfo info, StreamingContext context) : base(info, context)
        {
            ErrorCode = info.GetString("ErrorCode");
            Module = info.GetString("Module");
            IsFatal = info.GetBoolean("IsFatal");
        }

        /// <summary>
        /// 使用可序列化的数据填充SerializationInfo
        /// </summary>
        /// <param name="info">要填充数据的SerializationInfo</param>
        /// <param name="context">此序列化的目标</param>
        public override void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            base.GetObjectData(info, context);
            info.AddValue("ErrorCode", ErrorCode);
            info.AddValue("Module", Module);
            info.AddValue("IsFatal", IsFatal);
        }

        /// <summary>
        /// 获取包含错误代码的完整错误消息
        /// </summary>
        /// <returns>包含错误代码的完整错误消息</returns>
        public override string ToString()
        {
            return $"[{ErrorCode}] {Module}: {Message}";
        }
    }
} 